package cn.xiaolang.thread.threadlocal;

import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 自定义线程池，重置threadLocals，inheritableThreadLocals
 *
 * @author Dean
 * @date 2021-01-21
 */
@Slf4j
public class MyThreadPoolWithReset extends ThreadPoolExecutor {

    public MyThreadPoolWithReset(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }

    public MyThreadPoolWithReset(int corePoolSize,
                                 int maximumPoolSize,
                                 long keepAliveTime,
                                 TimeUnit unit,
                                 BlockingQueue<Runnable> workQueue,
                                 ThreadFactory threadFactory) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
                threadFactory);
    }


    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        Thread thread = Thread.currentThread();
        try {
            Field inheritableThreadLocalsField = Thread.class.getDeclaredField("inheritableThreadLocals");
            inheritableThreadLocalsField.setAccessible(true);
            inheritableThreadLocalsField.set(thread, null);

            Field threadLocalsField = Thread.class.getDeclaredField("threadLocals");
            threadLocalsField.setAccessible(true);
            threadLocalsField.set(thread, null);
        } catch (Exception e) {
            log.error("reset threadLocals exception:", e);
        }
    }
}